package com.sunducation.wts.databinding

import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.view.ViewStub
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import com.sunducation.wts.databinding.databinding.ActivityMainBinding
import com.sunducation.wts.databinding.databinding.LayoutIncludeBinding
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

/*
* DataBinding的好处
最直观的好处就是DataBinding可以帮我们减少很多没必要的代码，大大提高我们的开发效率。
* 比如大量减少使用findViewById()、setText()，setVisibility()，setEnabled()等代码的几率。

DataBinding主要解决了两个问题：
需要多次使用findViewById等无营养的代码，损害了应用性能且令人厌烦
更新UI数据需切换至UI线程，将数据分解映射到各个view比较麻烦
*
* */
class MainActivity : AppCompatActivity() {

    /*看到 ActivityMainBinding 了吗？就是它！那自动生成有什么规则了没？当然有了，记好了：
    将我们布局文件的首字母大写，并且去掉下划线，将下划线后面的字母大写，加上Binding组成。*/
    private lateinit var binding:ActivityMainBinding;
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //代替原来的setContentView(R.layout.activity_main)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.tvColor.setTextColor(Color.parseColor("#ff0000")) //有id可以直接使用
        //binding.root item中常用
        var user: User = User("火神", "祝融", 20)
        binding.user = user;

        binding.arrayKey = 0
        binding.listKey = 1
        binding.mapKey = "h1"
        val arr : Array<String> = arrayOf("a1", "a2")
        val al : ArrayList<String> = arrayListOf("al1", "al2")
        val hashMap : HashMap<String, String> = HashMap<String, String>()
        hashMap.put("h1","Java")
        hashMap.put("h2","SEO")
        hashMap.put("h3","Python")
        hashMap.put("h4","Kotlin")
        binding.testarray = arr
        binding.testlist = al
        binding.testmap = hashMap;

        binding.imageUrl = "http://newpage-test.oss-cn-hangzhou.aliyuncs.com/0070926d30fc4b1fbefdf4ba3a47fda2.jpg"


        binding.time = Date();

        //点击事件用
        binding.mainActivity = this;

        //新建类处理点击事件
        binding.handle = MyHandler();

        binding.viewStub.setOnInflateListener(object : ViewStub.OnInflateListener{
            override fun onInflate(p0: ViewStub?, p1: View?) {
                val viewStubBinding : LayoutIncludeBinding? = DataBindingUtil.bind(p1!!)
                viewStubBinding?.setUser(user);
            }
        })
        binding.myClickListener = object : View.OnClickListener{
            override fun onClick(p0: View?) {
                if (!binding.viewStub.isInflated()) {
                    binding.viewStub.getViewStub()?.inflate();
                }
            }
        }



        /*自动布局属性，某个自定义view中有setter方法
        DataBinding对于自定义属性支持非常好, 只要View中包含setter方法就可以直接在布局中使用该属性
        public void setCustomName(@NonNull final String customName) {
            mLastName.setText("吴彦祖");
        }
        然后直接使用(但是IDE没有代码补全)
        app:customName="@{@string/wuyanzu}"
        但是setter方法只支持单个参数. app:这个命名空间可以随意*/



        /*binding有这些方法需要注意
        void    addOnRebindCallback(OnRebindCallback listener)
// 添加绑定监听器, 可以在Variable被设置的时候回调

        void    removeOnRebindCallback(OnRebindCallback listener)
// 删除绑定监听器

        View    getRoot()
// 返回被绑定的视图对象

        abstract void   invalidateAll()
// 使所有的表达式无效并且立刻重新设置表达式. 会重新触发OnRebindCallback回调(可以看做重置)

        abstract boolean    setVariable(int variableId, Object value)
// 可以根据字段id来设置变量

        void    unbind()
// 解绑布局, ui不会根据数据来变化, 但是监听器还是会触发的


        abstract boolean    hasPendingBindings()
// 当ui需要根据当前数据变化时就会返回true(数据变化后有一瞬间)

        void    executePendingBindings()
// 强制ui立刻刷新数据,



        mDataBinding.addOnRebindCallback(new OnRebindCallback() {
            *//**
             * 绑定之前
             * @param binding
             * @return 如果返回true就会绑定布局, 返回false则取消绑定
             *//*
            @Override public boolean onPreBind(ViewDataBinding binding) {
                return false;
            }

            *//**
             * 如果取消绑定则回调该方法(取决于onPreBind的返回值)
             * @param binding
             *//*
            @Override public void onCanceled(ViewDataBinding binding) {
                super.onCanceled(binding);
            }

            *//**
             * 绑定完成
             * @param binding
             *//*
            @Override public void onBound(ViewDataBinding binding) {
                super.onBound(binding);
            }
        });


        DataBinding.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {

            *//**
             * 会在DataBinding设置数据的时候回调
             * @param sender DataBinding生成的类
             * @param propertyId Variable的id
             *//*
            @Override public void onPropertyChanged(Observable sender, int propertyId) {
                ActivityMainBinding databinding = (ActivityMainBinding) sender;
                switch (propertyId) {
                    case BR.data:
                    Log.d("日志", "(MainActivity.java:54) ___ Result = " + databinding.getData().getName());
                    break;
                    case BR.dataSecond:

                    break;
                }
            }
        });


        DataBinding不仅可以绑定Activity还可以绑定视图内容(View)


        static <T extends ViewDataBinding> T    getBinding(View view)

// 和getBinding不同的是如果视图没有绑定会去检查父容器是否被绑定
        static <T extends ViewDataBinding> T    findBinding(View view)


        // 根据传的BR的id来返回字符串类型. 可能用于日志输出
        static String   convertBrIdToString(int id)

        getDefaultComponent()

        setDefaultComponent(DataBindingComponent bindingComponent)

        setContentView*/

    }

    public fun onClick(view: View) {
        Toast.makeText(this,"主界面点击事件", Toast.LENGTH_LONG).show();

        //更新一下数据看看
        binding.user = User("斗圣", "孙悟空", 500)
    }

    public fun click3(str: String){
        Toast.makeText(this,"参数点击${str}", Toast.LENGTH_LONG).show();
    }

    public fun click4(view:View, str: String){
        Toast.makeText(this,"参数点击${str}", Toast.LENGTH_LONG).show();
    }
}
